home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / µSim 1.0.5 / FabLibsƒ / StdGetFolder.c < prev    next >
Encoding:
Text File  |  1995-06-05  |  7.4 KB  |  289 lines  |  [TEXT/CWIE]

  1. /*
  2. Copyright © 1993,1994 by Fabrizio Oddone
  3. ••• ••• ••• ••• ••• ••• ••• ••• ••• •••
  4. This source code is distributed as freeware: you can copy, exchange, modify this
  5. code as you wish. You may include this code in any kind of application: freeware,
  6. shareware, or commercial, provided that full credits are given.
  7. You may not sell or distribute this code for profit.
  8. */
  9.  
  10. /* I did not write the code in this file; I took it from some sample code
  11. from Apple, I think.
  12. I modified the original code a little bit, though. */
  13.  
  14. //#pragma load "MacDump"
  15. #ifndef __MOREFILESEXTRAS__
  16. #include "MoreFilesExtras.h"
  17. #endif
  18.  
  19. #include    "UtilsSys7.h"
  20. #include    "StdGetFolder.h"
  21.  
  22. /* typedefs */
  23.  
  24. typedef struct {
  25.     StandardFileReply *replyPtr;
  26.     void (*updateProc)(EventRecord *);
  27.     void (*activateProc)(EventRecord *);
  28.     FSSpec oldSelection;
  29.     short    SelectStrRsrc;
  30. //    short    DeskStrRsrc;
  31. } SFData, *SFDataPtr;
  32.  
  33. /* prototypes */
  34.  
  35. static pascal short MyDlgHook(short item, DialogPtr theDlg, SFDataPtr sfp);
  36. static pascal Boolean MyModalFilter(DialogPtr theDlg, EventRecord *ev, short *itemHit, SFDataPtr myData);
  37. //static pascal Boolean FilterAllFiles(CInfoPBPtr pb, Ptr myDataPtr);
  38. static void SetSelectButtonName(ConstStr255Param selName, const DialogPtr theDlg, short, Boolean);
  39. static Boolean SameFile(const FSSpecPtr file1, const FSSpecPtr file2);
  40. static OSErr GetDeskFolderSpec(FSSpecPtr, short vRefNum);
  41. static OSErr MakeCanonFSSpec(FSSpecPtr);
  42. static Boolean ShouldHiliteSelect(FSSpecPtr);
  43.  
  44. /* constants */
  45.  
  46. #define    kSelectItem            10
  47. #define    kCanSelectDesktop    true
  48. #define    kSelectKey            's'
  49.  
  50. /* globals */
  51.  
  52. Boolean    gHasFindFolder;
  53. FSSpec    gDeskFolderSpec;
  54.  
  55. /*
  56.     strHndl = GetString(kSelectStrRsrc);
  57.     strHndl = GetString(kDeskStrRsrc);
  58. */
  59.  
  60. /* do getfile */
  61.  
  62. Boolean CustomGet(FSSpec *fSpec,
  63.                 void (*DoUpdate)(EventRecord *),
  64.                 void (*DoActivate)(EventRecord *),
  65.                 short SFDlgID, short SelectStrRsrc/*, short DeskStrRsrc*/)
  66. {
  67. //FileFilterYDUPP    FilterAllFilesUPP = NewFileFilterYDProc(FilterAllFiles);
  68. DlgHookYDUPP    MyDlgHookUPP = NewDlgHookYDProc(MyDlgHook);
  69. ModalFilterYDUPP    MyModalFilterUPP = NewModalFilterYDProc(MyModalFilter);
  70. Point    where = {-1,-1};
  71. OSType    myType = 'ƒldr';
  72. StandardFileReply    sfReply;
  73. SFData    sfUserData;
  74. Boolean    targetIsFolder, wasAliased;
  75.  
  76. /* initialize user data area */
  77.  
  78. sfUserData.replyPtr = &sfReply;
  79. sfUserData.updateProc = DoUpdate;
  80. sfUserData.activateProc = DoActivate;
  81. sfUserData.oldSelection.vRefNum = -9999;    /* init to ridiculous value */
  82. sfUserData.SelectStrRsrc = SelectStrRsrc;
  83. //sfUserData.DeskStrRsrc = DeskStrRsrc;
  84.  
  85. CustomGetFile(nil, 1, &myType, &sfReply, SFDlgID, where, MyDlgHookUPP,
  86.                 MyModalFilterUPP, nil, nil, &sfUserData);
  87.  
  88. if (sfReply.sfGood) {
  89.     if (ResolveAliasFile(&sfReply.sfFile, true, &targetIsFolder, &wasAliased)) {
  90.         sfReply.sfGood = false;
  91.         }
  92.     else if (StrLength(sfReply.sfFile.name) == 0) {
  93.         (void) FSMakeFSSpecCompat(sfReply.sfFile.vRefNum, sfReply.sfFile.parID, nil, fSpec);
  94. //        sfReply.sfGood = false;
  95.         }
  96.     else
  97.         *fSpec = sfReply.sfFile;
  98.     }
  99.  
  100. if (MyModalFilterUPP)
  101.     DisposeRoutineDescriptor(MyModalFilterUPP);
  102. if (MyDlgHookUPP)
  103.     DisposeRoutineDescriptor(MyDlgHookUPP);
  104. //if (FilterAllFilesUPP)
  105. //    DisposeRoutineDescriptor(FilterAllFilesUPP);
  106.  
  107. return sfReply.sfGood;
  108. }
  109.  
  110.  
  111. /*    this dialog hook checks the contents of the additional edit fields
  112.     when the user selects a file.  The focus of the dialog is changed if one
  113.     of the fields is out of range.Ptr userData
  114. */
  115.  
  116. pascal short MyDlgHook(short item, DialogPtr theDlg, SFDataPtr sfUserData)
  117. {
  118. FSSpec curSpec;
  119.  
  120. if (GetWRefCon(GetDialogWindow(theDlg)) == sfMainDialogRefCon) {    
  121. //    sfUserData = (SFDataPtr) userData;
  122.     
  123.     if (item != sfHookFirstCall && item != sfHookLastCall) {
  124. /*        if (item == sfItemVolumeUser) {
  125.             sfUserData->replyPtr->sfFile.name[0] = '\0';
  126.             sfUserData->replyPtr->sfFile.parID = fsRtDirID;
  127.             sfUserData->replyPtr->sfIsFolder = false;
  128.             sfUserData->replyPtr->sfIsVolume = false;
  129.             sfUserData->replyPtr->sfFlags = 0;
  130.             item = sfHookChangeSelection;
  131.             }
  132. */
  133.         if (!SameFile(&sfUserData->replyPtr->sfFile, &sfUserData->oldSelection)) {
  134.             curSpec = sfUserData->replyPtr->sfFile;
  135.             (void)MakeCanonFSSpec(&curSpec);
  136.             
  137.             if (curSpec.vRefNum != sfUserData->oldSelection.vRefNum)
  138.                 GetDeskFolderSpec(&gDeskFolderSpec, curSpec.vRefNum);    
  139.             SetSelectButtonName(curSpec.name, theDlg, sfUserData->SelectStrRsrc, ShouldHiliteSelect(&curSpec));
  140.         
  141.             sfUserData->oldSelection = sfUserData->replyPtr->sfFile;
  142.             }
  143.  
  144.         if (item == kSelectItem)
  145.             item = sfItemOpenButton;
  146.         }
  147.     }
  148. return item;
  149. }
  150.  
  151.  
  152. pascal Boolean MyModalFilter(DialogPtr theDlg, EventRecord *ev, short *itemHit, SFDataPtr myData)
  153. {
  154. Boolean evHandled = false;
  155. char keyPressed;
  156.  
  157. if (GetWRefCon(GetDialogWindow(theDlg)) == sfMainDialogRefCon)
  158.     switch (ev->what) {
  159.         case keyDown:
  160.         case autoKey:
  161.             keyPressed = CHARFROMMESSAGE(ev->message);
  162.             if (ev->modifiers & cmdKey) {
  163.                 switch (keyPressed) {
  164.                     case kSelectKey:
  165.                         FlashButton(theDlg, kSelectItem);
  166.                         *itemHit = kSelectItem;
  167.                         evHandled = true;
  168.                         break;
  169.                 }
  170.             }
  171.             break;
  172.         case updateEvt:
  173.             if (theDlg != (DialogPtr)ev->message && myData->updateProc) {
  174.                 myData->updateProc(ev);
  175.                 evHandled = true;
  176.                 }
  177.             break;
  178.         case activateEvt:
  179.             if (theDlg != (DialogPtr)ev->message && myData->activateProc) {
  180.                 myData->activateProc(ev);
  181.                 evHandled = true;
  182.                 }
  183.             break;
  184.         }
  185.  
  186. return evHandled;
  187. }
  188.  
  189. /*
  190. pascal Boolean FilterAllFiles(CInfoPBPtr pb, Ptr myDataPtr)
  191. {
  192. return ((pb->hFileInfo.ioFlAttrib & (1 << 4)) == 0);
  193. }
  194. */
  195.  
  196. void SetSelectButtonName(ConstStr255Param selName, const DialogPtr theDlg, short SelectStrRsrc, Boolean hilited)
  197. {
  198. Str63    storeName, tempLenStr, tempSelName;
  199. Rect    iRect;
  200. StringHandle    theString;
  201. Handle    iHndl;
  202. short    iType;
  203.  
  204. (void) PLstrcpy(tempSelName, selName);
  205. GetDialogItem(theDlg, kSelectItem, &iType, &iHndl, &iRect);
  206.  
  207. /* truncate select name to fit in button */
  208.  
  209. theString = GetString(SelectStrRsrc);
  210.  
  211. (void) PLstrcpy(tempLenStr, *theString);
  212.  
  213. PLstrcat(tempLenStr, "\p “”  ");
  214. TruncString(iRect.right - iRect.left - StringWidth(tempLenStr), tempSelName, smTruncMiddle);
  215.  
  216. (void) PLstrcpy(storeName, *theString);
  217. PLstrcat(storeName, "\p “");
  218. PLstrcat(storeName, tempSelName);
  219. PLstrcat(storeName, "\p”");
  220.  
  221. SetControlTitle((ControlHandle)iHndl, storeName);
  222.  
  223. //SetDItem(theDlg,kSelectItem,iType,iHndl,&iRect);
  224.  
  225. HiliteControl((ControlHandle)iHndl, hilited ? 0 : 255);
  226. ValidRect(&iRect);
  227. }
  228.  
  229.  
  230. Boolean SameFile(const FSSpecPtr file1, const FSSpecPtr file2)
  231. {
  232. return ((file1->vRefNum == file2->vRefNum) &&
  233.         (file1->parID == file2->parID) &&
  234.         (EqualString(file1->name,file2->name,false,true)));
  235. }
  236.  
  237.  
  238. OSErr GetDeskFolderSpec(FSSpecPtr fSpec, short vRefNum)
  239. {
  240. register OSErr err = -1;
  241.  
  242. if (gHasFindFolder) {
  243.     StrLength(fSpec->name) = 0;
  244.     err = FindFolder(vRefNum, kDesktopFolderType, kDontCreateFolder,
  245.                         &fSpec->vRefNum,&fSpec->parID);
  246.     if (err == noErr)
  247.         err = MakeCanonFSSpec(fSpec);
  248.     }
  249. else
  250.     fSpec->vRefNum = -9999;
  251.  
  252. return err;
  253. }
  254.  
  255.  
  256. Boolean ShouldHiliteSelect(FSSpecPtr fSpec)
  257. {
  258. //StringHandle    strHndl;
  259.  
  260. if (CheckVolLock(nil, fSpec->vRefNum))
  261.     return false;
  262. else if (FSpCheckObjectLock(fSpec))
  263.     return false;
  264. else if (SameFile(fSpec, &gDeskFolderSpec)) {
  265. //    strHndl = GetString(DeskStrRsrc);
  266. //    (void) PLstrcpy(fSpec->name, *strHndl);
  267.     return kCanSelectDesktop;
  268.     }
  269. else
  270.     return true;
  271. }
  272.  
  273. OSErr MakeCanonFSSpec(FSSpecPtr fSpec)
  274. {
  275. DirInfo infoPB;
  276. OSErr err = noErr;
  277.  
  278. if (StrLength(fSpec->name) == 0) {
  279.     infoPB.ioNamePtr = fSpec->name;
  280.     infoPB.ioVRefNum = fSpec->vRefNum;
  281.     infoPB.ioDrDirID = fSpec->parID;
  282.     infoPB.ioFDirIndex = -1;
  283.     err = PBGetCatInfoSync((CInfoPBPtr)&infoPB);
  284.     fSpec->parID = infoPB.ioDrParID;
  285.     }
  286. return err;
  287. }
  288.  
  289.